import Cesium from '../../../public/tool/cesium/Cesium';
import { CesiumLayer } from './layer.js';
import { MAP_CONFIG } from '../config';
import Navigation from "../../js/SampleItems/SceneControl/Navigation";
import CommonVideoWindow from "../../js/SampleItems/CommonVideoWindow/index";
import MultiDetailWindow from "../../js/SampleItems/popup/MultiDetailWindow";

let cesiumInit = {
    init(el) {
        this.start = null;
        this.end = null;
        this.sceneTiles = null;
        this.videoWindow = null;
        // 视频弹框
        this.videoWindow = null;
        // 设备水质点
        this.infoWindow = null
        // Cesium授权token
        Cesium.Ion.defaultAccessToken = MAP_CONFIG.access_token;
        // 初始化地球
        this.viewer = new Cesium.Viewer(el, {
            animation: true,
            baseLayerPicker: true,
            fullscreenButton: true,
            geocoder: true,
            homeButton: true,
            infoBox: true,
            timeline: true,
            navigationHelpButton: true,
            vrButton: true,
            shouldAnimate: true
        });
        this.initViewer()
        this.addNavigation()
        // 加载tiles模型
        this.load3Dtiles('./model/tileset.json')
        // 修改默认鼠标交互
        this.initDefaultMouse(this.viewer)
        // // 视角飞行大屏
        // this.flytoChina()
     
        return this.viewer;
    },
    // 消除一些默认设置
    initViewer() {
        this.viewer.scene.fxaa = false; // 开启抗锯齿
        this.viewer.scene.moon.show = false;
        this.viewer.scene.sun.show = false;
        // this.viewer.resolutionScale = 0.9;
        // this.viewer.scene.globe.show = false
        // this.viewer.scene.screenSpaceCameraController.tiltEventTypes = [];
        this.viewer.scene.screenSpaceCameraController.enableTranslate = false
        // 去掉logo
        this.viewer._cesiumWidget._creditContainer.style.display = 'none';
        // 开启地形检测
        this.viewer.scene.globe.depthTestAgainstTerrain = false;
        // 指定日照时间，防止模型黑面
        let utc = Cesium.JulianDate.fromDate(new Date("2021/10/04 14:00:00"));
        this.viewer.clock.currentTime = Cesium.JulianDate.addHours(
        utc,
        0,
        new Cesium.JulianDate()
        );
    },
    // 指北针
    addNavigation() {
        let options = {};
        // 用于在使用重置导航重置地图视图时设置默认视图控制。接受的值是Cesium.Cartographic 和 Cesium.Rectangle.
        options.defaultResetView = Cesium.Cartographic.fromDegrees(
            117.15125666832741,
            38.94,
            8000
        );
        // 用于启用或禁用罗盘。true是启用罗盘，false是禁用罗盘。默认值为true。如果将选项设置为false，则罗盘将不会添加到地图中。
        options.enableCompass = true;
        // 用于启用或禁用缩放控件。true是启用，false是禁用。默认值为true。如果将选项设置为false，则缩放控件将不会添加到地图中。
        options.enableZoomControls = true;
        // 用于启用或禁用距离图例。true是启用，false是禁用。默认值为true。如果将选项设置为false，距离图例将不会添加到地图中。
        options.enableDistanceLegend = true;
        // 用于启用或禁用指南针外环。true是启用，false是禁用。默认值为true。如果将选项设置为false，则该环将可见但无效。
        options.enableCompassOuterRing = true;
        new Navigation(this.viewer, options);
    },
    // 重置鼠标动作
    initDefaultMouse(viewer) {
        viewer.scene.screenSpaceCameraController.tiltEventTypes = [
            Cesium.CameraEventType.RIGHT_DRAG
        ];
        // 平移 添加鼠标右键  鼠标右键平移
        viewer.scene.screenSpaceCameraController.rotateEventTypes = [
            Cesium.CameraEventType.LEFT_DRAG
        ];
        viewer.scene.screenSpaceCameraController.zoomEventTypes = [
            Cesium.CameraEventType.MIDDLE_DRAG,
            Cesium.CameraEventType.WHEEL,
            Cesium.CameraEventType.PINCH
        ];
    },
    // 加载倾斜摄影模型
    load3Dtiles(url) {
        if (this.sceneTiles) { return; }
        this.sceneTiles = CesiumLayer.createLayer({
            url: url,
            type: '3dtiles',
            name: '田地',
            offset: {
                z: 0
            }
        });
        this.flyTiles(this.sceneTiles)
        return this.sceneTiles;
    },
    toResetTiles () {
        this.flyTiles(this.sceneTiles)
    },
    // 定位到模型加载的位置
    flyTiles(tile) {
        if (!tile) { return; }
        this.viewer.scene.primitives.add(tile);
        this.viewer.flyTo(
            tile,
            new Cesium.HeadingPitchRange(Cesium.Math.toRadians(-45), Cesium.Math.toRadians(-45), 4000)
        );
    },
    /** 中国坐标 */
    getChinaPostion() {
        return Cesium.Cartesian3.fromDegrees(122.0843341, 30.24552894, 10000000.0);
    },
    //初始化点位
    initPoints(points) {
        points.forEach(item => {
        const point = item.point;
        let image = null
        if (item.type === 'monitor') {
            image = item.danger ? "./images/marker/bluecamera-red.png" : "./images/marker/bluecamera.png"
        } else if (item.type === 'system') {
            image = './images/marker/system.png'
        }
        this.viewer.entities.add({
            name: item.type + "&" + item.label,
            position: Cesium.Cartesian3.fromDegrees(point[0], point[1], point[2] + 20),
            info: item,
            billboard: {
                scale: 0.6,
                image: image,
                verticalOrigin: Cesium.VerticalOrigin.BOTTOM
            }
        });
        });
    },
    /**
     *  初始定位中国
     * */
    flytoChina() {
        this.viewer.camera.flyTo({
            destination: this.getChinaPostion(),
            duration: 3
        });
    },
    flyToPoint (lng, lat) {
        this.viewer.camera.flyTo({
            destination: Cesium.Cartesian3.fromDegrees(lng, lat, 1000.0),
            duration: 3
        });   
    },
    /***
     * TODO 测量计算长度
     * @param viewer
     * @param handler
     */
        measureLineSpace() {
        const _this = this
        let viewer = this.viewer
        // 取消双击事件-追踪该位置
        viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);

        this.handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);
        let positions = [];
        let poly = null;
        let distance = 0;
        let cartesian = null;
        this.handler.setInputAction(function (movement) {
            cartesian = viewer.scene.pickPosition(movement.endPosition);
            let ray = viewer.camera.getPickRay(movement.endPosition);
            cartesian = viewer.scene.globe.pick(ray, viewer.scene);
            if (positions.length >= 2) {
                if (!Cesium.defined(poly)) {
                    poly = new PolyLinePrimitive(positions);
                } else {
                    positions.pop();
                    positions.push(cartesian);
                }
                distance = getSpaceDistance(positions);
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        this.handler.setInputAction(function (movement) {
            let ray = viewer.camera.getPickRay(movement.position);
            cartesian = viewer.scene.globe.pick(ray, viewer.scene);
            if (positions.length === 0) {
                positions.push(cartesian.clone());
            }
            positions.push(cartesian);
            //在三维场景中添加Label
            let textDisance = distance + '公里';
            viewer.entities.add({
                name: 'MEAS_空间直线距离',
                position: positions[positions.length - 1],
                point: {
                    pixelSize: 5,
                    color: Cesium.Color.WHITE,
                    outlineColor: Cesium.Color.GOLD,
                    outlineWidth: 5,
                    pixelOffset: new Cesium.Cartesian2(20, -20),
                    heightReference: 3
                },
                label: {
                    text: textDisance,
                    font: '18px sans-serif',
                    fillColor: Cesium.Color.GOLD,
                    style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                    outlineWidth: 2,
                    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                    pixelOffset: new Cesium.Cartesian2(20, -20)
                }
            });
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        this.handler.setInputAction(function () {
            _this.handler.destroy(); //关闭事件句柄
            positions.pop(); //最后一个点无效

        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

        let PolyLinePrimitive = (function () {
            function _(positions) {
                this.options = {
                    name: 'MEAS_直线',
                    polyline: {
                        show: true,
                        positions: [],
                        material: Cesium.Color.CHARTREUSE,
                        width: 10,
                        clampToGround: true
                    }
                };
                this.positions = positions;
                this._init();
            }

            _.prototype._init = function () {
                let _self = this;
                let _update = function () {
                    return _self.positions;
                };
                //实时更新polyline.positions
                this.options.polyline.positions = new Cesium.CallbackProperty(_update, false);
                viewer.entities.add(this.options);
            };

            return _;
        })();

        //空间两点距离计算函数
        function getSpaceDistance(positions) {
            let distance = 0;
            for (let i = 0; i < positions.length - 1; i++) {

                let point1cartographic = Cesium.Cartographic.fromCartesian(positions[i]);
                let point2cartographic = Cesium.Cartographic.fromCartesian(positions[i + 1]);
                /**根据经纬度计算出距离**/
                let geodesic = new Cesium.EllipsoidGeodesic();
                geodesic.setEndPoints(point1cartographic, point2cartographic);
                let s = geodesic.surfaceDistance
                //返回两点之间的距离
                s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
                distance = distance + s;
            }
            return (distance / 1000).toFixed(2);
        }
    },
    /***
     * TODO 测量空间面积
     * ***/
        measureAreaSpace() {
        // const _this = this
        let viewer = this.viewer
        let handler = this.handler
        // 取消双击事件-追踪该位置
        viewer.cesiumWidget.screenSpaceEventHandler.removeInputAction(Cesium.ScreenSpaceEventType.LEFT_DOUBLE_CLICK);
        // 鼠标事件
        handler = new Cesium.ScreenSpaceEventHandler(viewer.scene._imageryLayerCollection);
        let positions = [];
        let tempPoints = [];
        let polygon = null;
        let cartesian = null;

        handler.setInputAction(function (movement) {
            let ray = viewer.camera.getPickRay(movement.endPosition);
            cartesian = viewer.scene.globe.pick(ray, viewer.scene);
            if (positions.length >= 2) {
                if (!Cesium.defined(polygon)) {
                    polygon = new PolygonPrimitive(positions);
                } else {
                    positions.pop();
                    positions.push(cartesian);
                }
            }
        }, Cesium.ScreenSpaceEventType.MOUSE_MOVE);

        handler.setInputAction(function (movement) {
            let ray = viewer.camera.getPickRay(movement.position);
            cartesian = viewer.scene.globe.pick(ray, viewer.scene);
            if (positions.length === 0) {
                positions.push(cartesian.clone());
            }
            //positions.pop();
            positions.push(cartesian);
            //在三维场景中添加点
            let cartographic = Cesium.Cartographic.fromCartesian(positions[positions.length - 1]);
            let longitudeString = Cesium.Math.toDegrees(cartographic.longitude);
            let latitudeString = Cesium.Math.toDegrees(cartographic.latitude);
            let heightString = cartographic.height;
            tempPoints.push({lon: longitudeString, lat: latitudeString, hei: heightString});
            viewer.entities.add({
                name: 'MEAS_多边形面积',
                position: positions[positions.length - 1],
                point: {
                    pixelSize: 5,
                    color: Cesium.Color.RED,
                    outlineColor: Cesium.Color.WHITE,
                    outlineWidth: 2,
                    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
                }
            });
        }, Cesium.ScreenSpaceEventType.LEFT_CLICK);

        handler.setInputAction(function () {
            handler.destroy();
            positions.pop();
            let textArea = getArea(tempPoints) + '平方公里';
            viewer.entities.add({
                name: 'MEAS_多边形面积',
                position: positions[positions.length - 1],
                label: {
                    text: textArea,
                    font: '18px sans-serif',
                    fillColor: Cesium.Color.GOLD,
                    style: Cesium.LabelStyle.FILL_AND_OUTLINE,
                    outlineWidth: 2,
                    verticalOrigin: Cesium.VerticalOrigin.BOTTOM,
                    pixelOffset: new Cesium.Cartesian2(20, -40),
                    heightReference: Cesium.HeightReference.CLAMP_TO_GROUND
                }
            });
        }, Cesium.ScreenSpaceEventType.RIGHT_CLICK);

        let radiansPerDegree = Math.PI / 180.0;//角度转化为弧度(rad)
        let degreesPerRadian = 180.0 / Math.PI;//弧度转化为角度

        //计算多边形面积
        function getArea(points) {
            let res = 0;
            //拆分三角曲面
            for (let i = 0; i < points.length - 2; i++) {
                let j = (i + 1) % points.length;
                let k = (i + 2) % points.length;
                let totalAngle = Angle(points[i], points[j], points[k]);
                let dis_temp1 = distance(positions[i], positions[j]);
                let dis_temp2 = distance(positions[j], positions[k]);
                res += dis_temp1 * dis_temp2 * Math.abs(Math.sin(totalAngle));
            }
            return (res / 1000000.0).toFixed(4);
        }

        /*角度*/
        function Angle(p1, p2, p3) {
            let bearing21 = Bearing(p2, p1);
            let bearing23 = Bearing(p2, p3);
            let angle = bearing21 - bearing23;
            if (angle < 0) {
                angle += 360;
            }
            return angle;
        }

        /*方向*/
        function Bearing(from, to) {
            let lat1 = from.lat * radiansPerDegree;
            let lon1 = from.lon * radiansPerDegree;
            let lat2 = to.lat * radiansPerDegree;
            let lon2 = to.lon * radiansPerDegree;
            let angle = -Math.atan2(Math.sin(lon1 - lon2) * Math.cos(lat2), Math.cos(lat1) * Math.sin(lat2) - Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon1 - lon2));
            if (angle < 0) {
                angle += Math.PI * 2.0;
            }
            angle = angle * degreesPerRadian;//角度
            return angle;
        }

        let PolygonPrimitive = (function () {
            function _(positions) {
                this.options = {
                    name: 'MEAS_多边形',
                    polygon: {
                        hierarchy: [],
                        material: Cesium.Color.GREEN.withAlpha(0.5)
                    }
                };

                this.hierarchy = {positions};
                this._init();
            }

            _.prototype._init = function () {
                let _self = this;
                let _update = function () {
                    return _self.hierarchy;
                };
                //实时更新polygon.hierarchy
                this.options.polygon.hierarchy = new Cesium.CallbackProperty(_update, false);
                viewer.entities.add(this.options);
            };

            return _;
        })();

        function distance(point1, point2) {
            let point1cartographic = Cesium.Cartographic.fromCartesian(point1);
            let point2cartographic = Cesium.Cartographic.fromCartesian(point2);
            /**根据经纬度计算出距离**/
            let geodesic = new Cesium.EllipsoidGeodesic();
            geodesic.setEndPoints(point1cartographic, point2cartographic);
            let s = geodesic.surfaceDistance;
            //返回两点之间的距离
            s = Math.sqrt(Math.pow(s, 2) + Math.pow(point2cartographic.height - point1cartographic.height, 2));
            return s;
        }
    },
    //监控选中事件
    selectedEntityMonitor(e, title) {
        if (!e) return;
        if (this.videoWindow) {
        this.videoWindow.close();
        this.videoWindow = null;
        }
        let info = { name: title, url: "" };
        this.videoWindow = new CommonVideoWindow(
        this.viewer,
            e.position._value,
            info
        );
    },
    // 设备水质点选中事件
    selectEntityInformation(e, title) {
        if (!e) return;
        if (this.infoWindow) {
        this.infoWindow.windowClose();
        this.infoWindow = null;
        }
        this.infoWindow = new MultiDetailWindow(
        this.viewer,
        e.position._value,
        title,
            ["设备编号", "设备名称", "所在位置", "化学含氧量"],
            ["SB019", "CODcr在线分析仪", "保育区", "1.358(mg|L)"]
        );
    },
    // 清除所有实体
    clearDraw() {
        this.viewer.entities.removeAll();//清除绘制的结果
    },
    // 清除测量
    removeMeas () {
        let values = [].concat(this.viewer.entities.values)
        values.forEach(item => {
            if (item.name && item.name.includes('MEAS')) {
                this.viewer.entities.remove(item)
            }
          });
    },

    destroy() {
        this.viewer.entities.removeAll();
        this.viewer.imageryLayers.removeAll(true);
        this.viewer.destroy();
    }
}
export default cesiumInit;

